namespace Guia.Elements
{
    using System;
    using System.Diagnostics.Contracts;
    using System.Windows.Automation;
    using Guia.Locator;

    /// <summary>
    /// This class represents a ListView. A ListView is a specialization of ListBox.
    /// </summary>
    public class ListView : ListBox
    {
        /// <summary>
        /// Initializes a new instance of the ListView class. 
        /// </summary>
        /// <param name="automationElement">The AutomationElement representating the ListView.</param>
        public ListView(AutomationElement automationElement)
            : base(automationElement)
        {
        }

        /// <summary>
        /// Gets the default-condition to find a control by its type.
        /// </summary>
        public static new SearchCondition ControlTypeCondition
        {
            get { return SearchCondition.ByControlType(ControlType.List).And(SearchCondition.ByClassName("ListView")); }
        }

        /// <summary>
        /// Gets the UiElement in the ListView of the given type and the given automationId. The element is searched in the whole subtree of this ListView. 
        /// </summary>
        /// <param name="automationId">
        /// The automationId of the desired UiElement. That can be the id of a particular ListViewItem or of any other descendant UiElement (e.g. a nested CheckBox).
        /// </param>
        /// <typeparam name="T">
        /// The type of the desired item.
        /// </typeparam>
        /// <returns>
        /// The desired UiElement of the ListView.
        /// </returns>
        /// <exception cref="ArgumentNullException">This exception is thrown if automationId is null</exception>
        public T GetSubItem<T>(string automationId) where T : UiElement
        {
            Contract.Requires<ArgumentNullException>(automationId != null);
            SearchCondition searchCondition = ControlTypeDirectory.GetConditionForType<T>().And(SearchCondition.ByAutomationId(automationId));
            searchCondition.Scope = TreeScope.Descendants;
            return this.Get<T>(searchCondition);
        }
    }
}